package com.zhilehuo.pretask.repo

import android.util.Log
import com.google.gson.GsonBuilder
import com.google.gson.JsonSyntaxException
import com.google.gson.reflect.TypeToken
import com.zhilehuo.pretask.adapter.Article
import com.zhilehuo.pretask.adapter.ArticlePage
import com.zhilehuo.pretask.adapter.Category
import com.zhilehuo.pretask.poko.ApiResponse
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call
import okhttp3.Callback
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import timber.log.Timber
import java.io.IOException
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

/**
 * @Description: 文章封面仓库类
 * @Author: Realnt
 * @Date:
 */
class LibraryRepository {
    private val client: OkHttpClient by lazy {
        /* 创建信任所有证书的客户端(测试用) */
        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
            override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
            override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
            override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
        })

        val sslContext = SSLContext.getInstance("SSL")
        sslContext.init(null, trustAllCerts, SecureRandom())

        OkHttpClient.Builder()
            .sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
            .hostnameVerifier { _, _ -> true } // 跳过主机名验证
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build()
    }
    private val gson = GsonBuilder().create()

    /**
     * @Description: 获取分类列表
     * @Param  :
     * @Return List<Category> : 返回的类别列表
     */
    suspend fun getCategories(): List<Category> {
        val request = Request.Builder()
            .url("https://test.shiqu.zhilehuo.com/englishgpt/library/articleTypeList")
            .build()

        return parseRequest(request)
    }

    /**
     * @Description: 获取难度列表
     * @Param  :
     * @Return List<Int> : 返回的难度列表
     */
    suspend fun getDifficulties(): List<Int> {
        val request = Request.Builder()
            .url("https://test.shiqu.zhilehuo.com/englishgpt/appArticle/selectList")
            .build()

        return parseRequest(request)
    }

    /**
     * @Description: 获取文章
     * @Param lexile : 难度
     * @Param typeId : 类别Id
     * @Param page : 页
     * @Param size : 页大小
     * @Return  :
     */
    suspend fun getArticles(
        lexile: Int,
        typeId: Int,
        page: Int,
        size: Int
    ): ArticlePage {
        val url = "https://test.shiqu.zhilehuo.com/englishgpt/library/articleList".toHttpUrlOrNull()!!.newBuilder()
            .addQueryParameter("lexile", lexile.toString())
            .addQueryParameter("typeId", typeId.toString())
            .addQueryParameter("page", page.toString())
            .addQueryParameter("size", size.toString())
            .build()

        val request = Request.Builder()
            .url(url)
            .addHeader("Cookie", "sid=OFvEbpyl4PyKkc/cSjl2tW3g5Ga/z5DPSQRGQn8mJBs=")
            .addHeader("Vary", "Accept-Encoding")
            .addHeader("Content-Encoding", "gzip")
            .build()

        return parseRequest(request)
    }

    /**
     * @Description: 发起并解析请求(完整流程记录)
     * @Param request : 请求
     * @Return T : 请求结果
     */
    private suspend inline fun <reified T> parseRequest(request: Request): T {
        return suspendCancellableCoroutine { continuation ->
            val call = client.newCall(request)

            // 绑定协程生命周期
            continuation.invokeOnCancellation {
                call.cancel()
            }

            call.enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    if (!call.isCanceled()) {
                        Timber.tag("Network").e(e, "Request failed")
                        continuation.resumeWithException(e)
                    }
                }

                override fun onResponse(call: Call, response: Response) {
                    /* 完整的流程日志记录 */
                    response.use {
                        // 记录响应状态码和消息
                        Timber.tag("MyNetWork").d("Response status: ${response.code} ${response.message}")

                        if (!response.isSuccessful) {
                            // 如果响应不成功，记录错误并抛出异常
                            val error = IOException("HTTP ${response.code}: ${response.message}")
                            Timber.tag("MyNetWork").e(error, "HTTP error")
                            continuation.resumeWithException(error)
                            return
                        }

                        try {
                            val responseBody = response.body?.string() ?: ""
                            // 记录完整的响应体
                            Timber.tag("MyNetWork").d("Response raw: $responseBody")

                            val type = object : TypeToken<ApiResponse<T>>() {}.type
                            val apiResponse = gson.fromJson<ApiResponse<T>>(responseBody, type)

                            when {
                                apiResponse.code != 0 -> {
                                    // 如果业务逻辑失败，记录错误并抛出异常
                                    val errorMsg = apiResponse.msg
                                    Timber.tag("MyNetWork").e("Business error: $errorMsg")
                                    continuation.resumeWithException(IOException(errorMsg))
                                }
                                apiResponse.data == null -> {
                                    // 如果数据字段为空，记录错误并抛出异常
                                    Timber.tag("MyNetWork").e("Data field is null")
                                    continuation.resumeWithException(IOException("Data field is null"))
                                }
                                else -> {
                                    // 如果一切正常，记录成功并返回数据
                                    Timber.tag("MyNetWork").d("Request successful")
                                    continuation.resume(apiResponse.data)
                                }
                            }
                        } catch (e: Exception) {
                            // 如果解析失败，记录错误并抛出异常
                            Timber.tag("MyNetWork").e(e, "Parsing error")
                            continuation.resumeWithException(e)
                        }
                    }
                }
            })
        }
    }
}